/****************************************************************************************
**  File: Drawing.hpp
**  Author: Asteroth
**  Date: 3-mag-2009
****************************************************************************************/

#ifndef __DRAWING_HPP__
#define __DRAWING_HPP__

class Drawing
{
	private:
		core::Color color;
		core::Color backColor;


	public:
		Drawing() {
			color = core::Color(255, 255, 255, 255);
			backColor = core::Color(0, 0, 0, 255);
		}

		~Drawing() {}

		inline void setColor(ubyte red, ubyte green, ubyte blue, ubyte alpha = 255) {
			color.R = red;
			color.G = green;
			color.B = blue;
			color.A = alpha;
		}

		inline void setColor(const core::Color &color) {this->color = color;}

		inline void setBackColor(ubyte red, ubyte green, ubyte blue, ubyte alpha = 0) {
			backColor.R = red;
			backColor.G = green;
			backColor.B = blue;
			backColor.A = alpha;
		}

		inline void setBackColor(const core::Color &color) {this->backColor = color;}

		inline void setLineWidth(float width) {glLineWidth(width);}

		inline core::Color getColor() const {return color;}

		inline core::Color getBackColor() const {return backColor;}

		inline float getLineWidth() const {
			float val;
			glGetFloatv(GL_LINE_WIDTH, &val);
			return val;
		}

		inline void enableLineSmooth(bool enable) {
			if (enable)
				glEnable(GL_LINE_SMOOTH);
			else
				glDisable(GL_LINE_SMOOTH);
		}

		inline bool isEnabledLineSmooth() {return (bool)glIsEnabled(GL_LINE_SMOOTH);}

		inline void drawLine(float x1, float y1, float x2, float y2, float depth = GD_DEFAULT_DEPTH) const {
			glBegin(GL_LINES);
				glColor4ub(color.R, color.G, color.B, color.A);
				glVertex3f(x1, y1, depth);
				glVertex3f(x2, y2, depth);
			glEnd();
		}

		inline void drawRectangle(float x, float y, float width, float height, bool fill = false, float depth = GD_DEFAULT_DEPTH) const {
			if (fill)
			{
				glBegin(GL_QUADS);
					glColor4ub(color.R, color.G, color.B, color.A);
					glVertex3f(x, y-1, depth);
					glVertex3f(x, y+height-1, depth);
					glVertex3f(x+width, y+height-1, depth);
					glVertex3f(x+width, y, depth);
					glVertex3f(x, y-1, depth);
				glEnd();
			}
			else
			{
				glBegin(GL_LINE_STRIP);
					glColor4ub(color.R, color.G, color.B, color.A);
					glVertex3f(x, y, depth);
					glVertex3f(x, y+height-1, depth);
					glVertex3f(x+width-1, y+height-1, depth);
					glVertex3f(x+width-1, y, depth);
					glVertex3f(x, y, depth);
				glEnd();
			}
		}

		inline void drawEllipse(float x, float y, float width, float height, bool fill = false, float depth = GD_DEFAULT_DEPTH) const {
			width /= 2.0;
			height /= 2.0;
			float div = (int)(12 + (width+height)/10);

			if (fill)
			{
				glBegin(GL_TRIANGLE_FAN);
					glColor4ub(color.R, color.G, color.B, color.A);
					glVertex3f(x, y, depth);
					for (float i=0; i<=div; i++)
						glVertex3f(x+cos(i*(core::PIm2/div))*width, y+sin(i*(core::PIm2/div))*height, depth);
				glEnd();
			}
			else
			{
				glBegin(GL_LINE_STRIP);
					glColor4ub(color.R, color.G, color.B, color.A);
					for (float i=0; i<=div; i++)
						glVertex3f(x+cos(i*(core::PIm2/div))*width, y+sin(i*(core::PIm2/div))*height, depth);
				glEnd();
			}
		}

		inline void drawTexture(const Texture &texture, float x, float y, float width, float height, float depth = GD_DEFAULT_DEPTH) const {
			glBindTexture(GL_TEXTURE_2D, texture.getHandle());

			glBegin(GL_QUADS);
				glColor4ub(color.R, color.G, color.B, color.A);
				glTexCoord2f(0.0f, 1.0f);
				glVertex3f(x, y-1, depth);
				glTexCoord2f(0.0f, 0.0f);
				glVertex3f(x, y+height-1, depth);
				glTexCoord2f(1.0f, 0.0f);
				glVertex3f(x+width, y+height-1, depth);
				glTexCoord2f(1.0f, 1.0f);
				glVertex3f(x+width, y, depth);
			glEnd();
		}

};

#endif
